package com.aiyan.edu.govern.gateway.filter;

import com.aiyan.edu.framework.canary.context.CanaryContextHolder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.Ordered;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;

/**
 * 灰度发布过滤器
 *
 * @author: zqzhou
 * @create: 2019/12/04 21:45
 **/
@Component
public class CanaryFilter implements GlobalFilter, Ordered {

    @Value("${aiyanedu.canary.users:test}")
    String canaryUsers;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        ServerHttpRequest request = exchange.getRequest();

        // 获取Authorize过滤器设置的用户信息头
        List<String> headers = request.getHeaders().get(AuthorizeGatewayFilterFactory.Authorize_UserName);
        String username = null;
        if (null != headers) {
            username = headers.get(0);
        }
        // 灰度用户的请求
        if (username != null && canaryUsers.contains(username)) {

            // 这里设置的值是传递给网关本身通过ribbon调用微服务时使用
            CanaryContextHolder.setCanaryContext(CanaryContextHolder.CANARY_META_VALUE);

            //传递给后续微服务
            ServerHttpRequest buildRequest = request.mutate().header(CanaryContextHolder.CANARY_META_KEY, CanaryContextHolder.CANARY_META_VALUE).build();
            ServerWebExchange build = exchange.mutate().request(buildRequest).build();
//                request.getHeaders().set(CanaryContextHolder.CANARY_META_KEY, name);

            //上面的逻辑是pre阶段执行

            // post阶段执行
            return chain.filter(build).then(Mono.fromRunnable(() -> {
                CanaryContextHolder.destroy();
            }));
        } else {
            CanaryContextHolder.setCanaryContext(null);
        }

        return chain.filter(exchange).then(Mono.fromRunnable(() -> {
            CanaryContextHolder.destroy();
        }));
    }

    @Override
    public int getOrder() {
        return 200;
    }
}
